#define _USE_MATH_DEFINES

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <queue>
#include <cassert>
#include <stack>
#include <cstdlib>
#include <bitset>
#include <cmath>

#define forn(i,n) for (int i = 0; i < int(n); ++i)
#define pb push_back
#define all(a) a.begin(),a.end()
#define sz(a) int(a.size())
#define mp make_pair

using namespace std;

typedef long long li;
typedef long double ld;

typedef pair<int,int> pt;
#define ft first
#define sc second

const int INF = int(1e9);
const li INF64 = li(1e18);
const ld EPS = 1e-9;

//#define TASK_NAME ""

const int N = 100005;

int g[N][4];
int n, t;

bool read() {
	if (scanf("%d%d", &n, &t) != 2)
		return false;
	t--;
	forn (i, n)
	{
		forn (j, 4)
		{
			scanf("%d", &g[i][j]);
			g[i][j]--;
		}
	}
	return true;
}

int p[N * 10];
int rnk[N * 10];
bool good[N * 10];

int back(int v, int id)
{
	int to = g[v][id];
	forn (i, 4)
		if (g[to][i] == v)
			return (i + 2) & 3;
	assert(false);
}

int leader(int v)
{
	return p[v] == v ? v : p[v] = leader(p[v]);
}

void merge(int a, int b)
{
	a = leader(a), b = leader(b);
	if (a != b)
	{
		if (rnk[a] < rnk[b])
			swap(a, b);
		p[a] = b;
		rnk[b] = rnk[b] + (rnk[a] == rnk[b]);
		good[b] |= good[a];
	}
}

void solve() {

	forn (i, n * 4)
		p[i] = i, rnk[i] = 1, good[i] = (i >> 2) == t;

	forn (i, n)
		forn (j, 4)
			merge(i * 4 + j, g[i][j] * 4 + back(i, j));

	int ans = 0;

	forn (i, n)
	{
		int cnt = 0;
		forn (j, 4)
			cnt += good[leader(i * 4 + j)];
		if (cnt < 4 && cnt > 0)
		{
			forn (j, 4)
				if (!good[leader(i * 4 + j)])
					good[leader(i * 4 + j)] = true;
			ans++;
		}
	}
	printf("%d\n", ans);
}

int main() {
#ifdef TASK_NAME
	freopen(TASK_NAME ".in", "r", stdin);
	freopen(TASK_NAME ".out", "w", stdout);
#endif

#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	int t;
	scanf("%d", &t);
	while (read())
		solve();

	return 0;
}